package com.njtoyo.taxi.admin.service.business.driver.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njtoyo.taxi.admin.cache.SecondaryCachePutter;
import com.njtoyo.taxi.admin.logic.business.driver.DriverSpecialRewardRuleLogic;
import com.njtoyo.taxi.admin.mapper.master.entity.DriverSpecialRewardRule;
import com.njtoyo.taxi.admin.mapper.master.entity.GeoDriverRegion;
import com.njtoyo.taxi.admin.mapper.master.mapper.DriverMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.DriverSpecialRewardRuleMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.GeoDriverRegionMapper;
import com.njtoyo.taxi.admin.rest.presenter.business.driver.QuerySpecialRewardRuleDetailPresenter;
import com.njtoyo.taxi.admin.rest.presenter.business.driver.QuerySpecialRewardRuleListPresenter;
import com.njtoyo.taxi.admin.rest.presenter.business.driver.QuerySpecialRewardRulePickRidePresenter;
import com.njtoyo.taxi.admin.rest.wrapper.business.driver.*;
import com.njtoyo.taxi.admin.service.business.driver.DriverSpecialReward;
import com.taxi.entity.common.RestResult;
import com.taxi.entity.common.ResultEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toSet;

@Service
public class DriverSpecialRewardImpl implements DriverSpecialReward {
    @Autowired
    private DriverSpecialRewardRuleMapper driverSpecialRewardRuleMapper;

    @Autowired
    private GeoDriverRegionMapper geoDriverRegionMapper;

    @Autowired
    private SecondaryCachePutter secondaryCachePutter;

    @Autowired
    private DriverSpecialRewardRuleLogic driverSpecialRewardRuleLogic;

    @Autowired
    private DriverMapper driverMapper;

    @Override
    public RestResult<Boolean> createRule(CreateSpecialRewardRuleWrapper wrapper) {
        DriverSpecialRewardRule driverSpecialRewardRule = BeanUtil.copyProperties(wrapper, DriverSpecialRewardRule.class);

        driverSpecialRewardRuleMapper.insert(driverSpecialRewardRule);

        return RestResult.success(true);
    }

    @Override
    public RestResult<Boolean> updateRule(Long id, UpdateSpecialRewardRuleWrapper wrapper) {
        // 校验是否存在
        DriverSpecialRewardRule rule = driverSpecialRewardRuleMapper.selectById(id);

        if (ObjectUtils.isEmpty(rule)) {
            return RestResult.build(ResultEnum.NOT_FOUND);
        }

        DriverSpecialRewardRule update = BeanUtil.copyProperties(wrapper, DriverSpecialRewardRule.class);
        update.setId(id);

        driverSpecialRewardRuleMapper.updateById(update);

        return RestResult.success(true);
    }

    @Override
    public RestResult<IPage<QuerySpecialRewardRuleListPresenter>> getRuleList(QuerySpecialRewardRuleListWrapper wrapper) {
        Page<DriverSpecialRewardRule> page = new Page<>(wrapper.getCurrent(), wrapper.getSize());

        IPage<DriverSpecialRewardRule> list = new LambdaQueryChainWrapper<>(driverSpecialRewardRuleMapper)
                .eq(ObjectUtil.isNotEmpty(wrapper.getDriverRegionId()), DriverSpecialRewardRule::getDriverRegionId, wrapper.getDriverRegionId())
                .eq(ObjectUtil.isNotEmpty(wrapper.getCategory()), DriverSpecialRewardRule::getCategory, wrapper.getCategory())
                .eq(ObjectUtil.isNotEmpty(wrapper.getRuleType()), DriverSpecialRewardRule::getRuleType, wrapper.getRuleType())
                .orderByDesc(DriverSpecialRewardRule::getId)
                .page(page);

        if (ObjectUtil.isEmpty(list.getRecords())) {
            return RestResult.success(new Page<>());
        }

        // 查 司机运营区
        Set<Long> driverRegionIds = list.getRecords().stream().map(DriverSpecialRewardRule::getDriverRegionId).collect(toSet());

        Map<Long, String> driverRegionMap = null;
        if (ObjectUtil.isNotEmpty(driverRegionIds)) {
            List<GeoDriverRegion> driverRegionList = new LambdaQueryChainWrapper<>(geoDriverRegionMapper)
                    .in(GeoDriverRegion::getId, driverRegionIds)
                    .list();

            if (ObjectUtil.isNotEmpty(driverRegionList)) {
                driverRegionMap = driverRegionList.stream().collect(Collectors.toMap(GeoDriverRegion::getId, GeoDriverRegion::getName));
            }
        }

        Map<Long, String> finalDriverRegionMap = driverRegionMap;
        IPage<QuerySpecialRewardRuleListPresenter> res = list.convert(i -> {
            QuerySpecialRewardRuleListPresenter item = BeanUtil.copyProperties(i, QuerySpecialRewardRuleListPresenter.class);
            if (Objects.nonNull(finalDriverRegionMap)) {
                item.setDriverRegionName(finalDriverRegionMap.getOrDefault(i.getDriverRegionId(), null));
            }

            // isRandomTime
            item.setIsRandomTime(!secondaryCachePutter.hasDriverSpecialRewardRule(i.getId()));

            return item;
        });

        return RestResult.success(res);
    }

    @Override
    public RestResult<QuerySpecialRewardRuleDetailPresenter> getRuleDetail(Long id) {
        // 校验是否存在
        DriverSpecialRewardRule rule = driverSpecialRewardRuleMapper.selectById(id);

        if (ObjectUtils.isEmpty(rule)) {
            return RestResult.build(ResultEnum.NOT_FOUND);
        }

        QuerySpecialRewardRuleDetailPresenter res = BeanUtil.copyProperties(rule, QuerySpecialRewardRuleDetailPresenter.class);

        return RestResult.success(res);
    }

    @Override
    public RestResult<Boolean> randomTimeGiveSpecialReward(Long id, RandomTimeGiveSpecialRewardWrapper wrapper) {
        // 校验是否存在
        DriverSpecialRewardRule rule = driverSpecialRewardRuleMapper.selectById(id);

        if (ObjectUtils.isEmpty(rule)) {
            return RestResult.build(ResultEnum.NOT_FOUND);
        }

        try {
            driverSpecialRewardRuleLogic.randomTimeGiveSpecialReward(rule, wrapper.getPeriodCount());
        } catch (Exception e) {
            e.printStackTrace();
            return RestResult.failed(e.getMessage());
        }

        return RestResult.success(true);
    }

    @Override
    public RestResult<Boolean> giveDriverSpecialReward(GiveDriverSpecialRewardWrapper wrapper) {
        try {
            driverSpecialRewardRuleLogic.giveDriverSpecialReward(wrapper.getRewardDetail());
        } catch (Exception e) {
            e.printStackTrace();
            return RestResult.failed(e.getMessage());
        }

        return RestResult.success(true);
    }

    @Override
    public RestResult<List<QuerySpecialRewardRulePickRidePresenter>> pickRideRank(QuerySpecialRewardRulePickRideWrapper wrapper) {
        List<QuerySpecialRewardRulePickRidePresenter> res = driverMapper.pickRideRank(wrapper.getCantonId(), wrapper.getStartTime(), wrapper.getEndTime());

        return RestResult.success(res);
    }
}
